<template>
	<div class="tooth">
		<div class="toothPosition">
			<div v-for="section in sections" :key="section.name" class="toothPosition-item" :style="{ height: `${height}px`, padding: `${padding}` }">
				<div v-for="tooth in section.teeth" :key="tooth.id" class="toothPosition-item-tooth" :class="{ toothdisabled: disabled }" :style="toothStyle(tooth)" @click="handleToothClick(tooth)">
					{{ tooth.displayId }}
				</div>
			</div>
		</div>
		<div class="action">
			<el-checkbox tabindex="-1" v-model="ymaxillary" label="上颌" :disabled="disabled" size="large" @change="handleJawChange('maxillary')" />
			<el-checkbox tabindex="-1" v-model="ymandibular" label="下颌" :disabled="disabled" size="large" @change="handleJawChange('mandibular')" />
		</div>
	</div>
</template>

<script setup>
	import { onMounted, ref, watch } from 'vue';
	import { findAdjacentPairs, separateAdjacentAndNonAdjacent } from '@/utils/PlaceOrder.js';
	import { useRoute } from 'vue-router';
	import { debounce } from 'lodash-es';
	import { ElMessage } from 'element-plus';

	const props = defineProps({
		height: { type: Number, default: 25 },

		padding: { type: String, default: '10px' },
		/** 是否上颌 */
		maxillary: { type: Boolean, default: false },
		/** 单冠 */
		singular: { type: Array, default: () => [] },
		/** 双冠 */
		double: { type: Array, default: () => [] },
		// 是否禁止点击
		disabled: { type: Boolean, default: false },
		//关键词匹配牙位
		tooth_position_key: { type: String, default: '' },
		//左上关键词匹配牙位
		tooth_left_up_key: { type: String, default: '' },
		//右上关键词匹配牙位
		tooth_right_up_key: { type: String, default: '' },
		//左下关键词匹配牙位
		tooth_left_down_key: { type: String, default: '' },
		//右下关键词匹配牙位
		tooth_right_down_key: { type: String, default: '' }
	});

	const emit = defineEmits(['change', 'click', 'update']);

	const route = useRoute();

	// 创建牙齿数据
	const createTeeth = (start, end, reverse) => {
		const teeth = [];
		let i = start;
		const step = reverse ? -1 : 1;
		while (reverse ? i >= end : i <= end) {
			teeth.push({ id: i, displayId: i % 10, style: { backgroundColor: '#eef4f1', color: 'black' } });
			i += step;
		}
		return teeth;
	};

	// 定义牙齿列表
	const sections = ref([
		{ name: 'upper-left', teeth: createTeeth(18, 11, true) },
		{ name: 'upper-right', teeth: createTeeth(21, 28) },
		{ name: 'lower-left', teeth: createTeeth(48, 41, true) },
		{ name: 'lower-right', teeth: createTeeth(31, 38) }
	]);

	/** 上颌 */
	const ymaxillary = ref(false);
	/** 下颌 */
	const ymandibular = ref(false);

	/** 单冠牙齿 */
	let singular = ref(props.singular);

	/** 双冠牙齿 */
	let double = ref(props.double);

	//监听左上关键词匹配
	watch(
		() => props.tooth_left_up_key,
		() => {
			dangeKeywrdTooth(props.tooth_left_up_key, 1);
		},
		{ deep: true }
	);
	watch(
		() => props.tooth_right_up_key,
		() => {
			dangeKeywrdTooth1(props.tooth_right_up_key, 2);
		},
		{ deep: true }
	);
	watch(
		() => props.tooth_left_down_key,
		() => {
			dangeKeywrdTooth2(props.tooth_left_down_key, 4);
		},
		{ deep: true }
	);
	watch(
		() => props.tooth_right_down_key,
		() => {
			dangeKeywrdTooth3(props.tooth_right_down_key, 3);
		},
		{ deep: true }
	);

	//处理单个关键词逻辑
	const dangeKeywrdTooth = debounce((keyword, type) => {
		//如果关键词为空
		if (!keyword) {
			return;
		}

		//定义正则 匹配当前的字符串内容是1到8之间的数字
		const regex = /^[1-8]+$/;
		if (!regex.test(keyword)) {
			ElMessage.error('请输入1到8之间的数字');
			return;
		}

		//把拿到的关键词进行往首位拼接type
		keyword = type + keyword;

		//如果第一个字符不是1 则提示
		if (keyword[0] != type) {
			ElMessage.error(`请输入${type}开头的关键词`);
			return;
		}

		setD1(keyword);
		emit('update', type);
	}, 500);

	//处理单个关键词逻辑
	const dangeKeywrdTooth1 = debounce((keyword, type) => {
		//如果关键词为空
		if (!keyword) {
			return;
		}

		//定义正则 匹配当前的字符串内容是1到8之间的数字
		const regex = /^[1-8]+$/;
		if (!regex.test(keyword)) {
			ElMessage.error('请输入1到8之间的数字');
			return;
		}

		//把拿到的关键词进行往首位拼接type
		keyword = type + keyword;

		//如果第一个字符不是1 则提示
		if (keyword[0] != type) {
			ElMessage.error(`请输入${type}开头的关键词`);
			return;
		}

		setD1(keyword);
		emit('update', type);
	}, 500);

	//处理单个关键词逻辑
	const dangeKeywrdTooth2 = debounce((keyword, type) => {
		//如果关键词为空
		if (!keyword) {
			return;
		}

		//定义正则 匹配当前的字符串内容是1到8之间的数字
		const regex = /^[1-8]+$/;
		if (!regex.test(keyword)) {
			ElMessage.error('请输入1到8之间的数字');
			return;
		}

		//把拿到的关键词进行往首位拼接type
		keyword = type + keyword;

		//如果第一个字符不是1 则提示
		if (keyword[0] != type) {
			ElMessage.error(`请输入${type}开头的关键词`);
			return;
		}

		setD1(keyword);
		emit('update', type);
	}, 500);

	//处理单个关键词逻辑
	const dangeKeywrdTooth3 = debounce((keyword, type) => {
		//如果关键词为空
		if (!keyword) {
			return;
		}

		//定义正则 匹配当前的字符串内容是1到8之间的数字
		const regex = /^[1-8]+$/;
		if (!regex.test(keyword)) {
			ElMessage.error('请输入1到8之间的数字');
			return;
		}

		//把拿到的关键词进行往首位拼接type
		keyword = type + keyword;

		//如果第一个字符不是1 则提示
		if (keyword[0] != type) {
			ElMessage.error(`请输入${type}开头的关键词`);
			return;
		}

		setD1(keyword);
		emit('update', type);
	}, 500);

	//监听关键词匹配
	watch(
		() => props.tooth_position_key,
		() => {
			updateKeywordTooth(props.tooth_position_key);
		},
		{ deep: true }
	);

	//处理关键词匹配牙位逻辑
	const updateKeywordTooth = debounce(async (keyword) => {
		console.log('props.tooth_position_key', keyword, typeof keyword);

		//如果关键词为空，则清空
		if (!keyword) {
			return;
		}
		singular.value = [];
		double.value = [];
		/**
		 * 1.代表上颚
		 * 2.代表下颚
		 * 0.代表全口
		 */
		switch (keyword) {
			case '1':
				//如果是单冠 赋值singular //否则双冠 赋值double
				if (!props.maxillary) {
					singular.value = [11, 12, 13, 14, 15, 16, 17, 18, 21, 22, 23, 24, 25, 26, 27, 28];
				} else {
					double.value = [11, 12, 13, 14, 15, 16, 17, 18, 21, 22, 23, 24, 25, 26, 27, 28];
				}
				break;
			case '2':
				if (!props.maxillary) {
					singular.value = [31, 32, 33, 34, 35, 36, 37, 38, 41, 42, 43, 44, 45, 46, 47, 48];
				} else {
					double.value = [31, 32, 33, 34, 35, 36, 37, 38, 41, 42, 43, 44, 45, 46, 47, 48];
				}
				break;
			case '0':
				if (!props.maxillary) {
					singular.value = [11, 12, 13, 14, 15, 16, 17, 18, 21, 22, 23, 24, 25, 26, 27, 28, 31, 32, 33, 34, 35, 36, 37, 38, 41, 42, 43, 44, 45, 46, 47, 48];
				} else {
					double.value = [11, 12, 13, 14, 15, 16, 17, 18, 21, 22, 23, 24, 25, 26, 27, 28, 31, 32, 33, 34, 35, 36, 37, 38, 41, 42, 43, 44, 45, 46, 47, 48];
				}
				break;

			default:
				//判断是否符合格式 12344.1232.123421 或者 11-2.21-5
				// const strictRegex = /^[1-8]{1,8}(?:[.][1-8]{1,8})*$/;
				const strictRegex = /^[1-8]{1,8}(?:[.][1-8]{1,8})*$|^[1-8]{2}-[1-8](\.[1-8]{1}-[1-8])?$/;
				if (!strictRegex.test(keyword)) {
					ElMessage.error('请输入正确关键词');
					return;
				}
				// //1.有. 说明是多区 按.分割  单独循环处理单个区追加赋值
				// //2.无. 说明是单独区
				let isHave = keyword.indexOf('.');

				//英文分割
				if (isHave != -1) {
					let arr = keyword.split('.');
					//校验是否是1,2,3,4开头
					let res = is1234(arr);
					if (!res) {
						ElMessage.error('请使用1,2,3,4开头的数字');
						return;
					}
					arr.forEach((item) => {
						setD1(item);
					});
				} else {
					//单个
					//校验是否是1,2,3,4开头
					let res = is1234(keyword);
					if (!res) {
						ElMessage.error('请使用1,2,3,4开头的数字');
						return;
					}
					setD1(keyword);
				}

				console.log(singular.value);
				break;
		}

		emit('update', '5');
	}, 500);

	//处理数字结构 传入12-15 返回[12,13,14,15]
	// const strToarr = (str) => {
	// 	let arr = str.split('-');
	// 	let newArr = [];
	// 	for (let i = arr[0]; i <= arr[1]; i++) {
	// 		newArr.push(Number(i));
	// 	}
	// 	console.log(newArr);
	// 	return newArr;
	// };

	//赋值
	// const setD = (item) => {
	// 	//判断是否有-
	// 	let isHeng = item.indexOf('-');
	// 	if (isHeng != -1) {
	// 		if (!props.maxillary) {
	// 			singular.value.push(...strToarr(item));
	// 		} else {
	// 			double.value.push(...strToarr(item));
	// 		}
	// 	} else {
	// 		if (!props.maxillary) {
	// 			singular.value.push(Number(item));
	// 		} else {
	// 			double.value.push(Number(item));
	// 		}
	// 	}
	// };

	//判断当前是否是1或者2或者3或者4开头
	const is1234 = (str) => {
		//判断当前类型是否是数组 或者 字符串
		if (!Array.isArray(str) && typeof str !== 'string') {
			return false;
		}

		//判断当前是数组还是字符串
		if (Array.isArray(str)) {
			//数组 循环判断
			for (let i = 0; i < str.length; i++) {
				//判断每一项的第一位是否是1或者2或者3或者4
				if (!str[i].match(/^[1-4]/)) {
					return false;
				}
			}
		}
		if (typeof str === 'string') {
			//字符串 判断第一位是否是1或者2或者3或者4
			if (!str.match(/^[1-4]/)) {
				return false;
			}
		}

		return true;
	};

	/**
	 * 处理结构
	 * @param item 输入的字符串
	 * 传入11234 返回 11，12，13，14
	 * 传入11-5 返回 11，12，13，14，15
	 */
	const strToarr1 = (item) => {
		let arr = [];

		//检查item中是否有-
		let isHeng = item.indexOf('-');

		//有-
		if (isHeng != -1) {
			//保存字符串的第一项
			let firstChar = item.charAt(0);

			//删除掉字符串的第一项
			item = item.substring(1);

			let arr1 = item.split('-');
			for (let i = arr1[0]; i <= arr1[1]; i++) {
				let aa = firstChar + i;
				arr.push(Number(aa));
			}
			return arr;
		}
		//没有-
		if (isHeng == -1) {
			//分割符串
			let itemList = item.split('');
			//保存第一项
			let firstItem = itemList[0];

			//把itemList的第一项删除
			itemList.splice(0, 1);

			for (let i = 0; i < itemList.length; i++) {
				let aa = firstItem + itemList[i];
				arr.push(Number(aa));
			}
			return arr;
		}
	};

	//赋值
	const setD1 = (item) => {
		if (!props.maxillary) {
			singular.value.push(...strToarr1(item));
			//去重
			singular.value = [...new Set(singular.value)];
		} else {
			double.value.push(...strToarr1(item));
			//去重
			double.value = [...new Set(double.value)];
		}
	};

	// 监听传入的牙位数据
	watch(
		[singular, double, route],
		() => {
			updateWtchStyle();
		},
		{ deep: true }
	);

	watch(route, () => updateStyles(), { deep: true });

	// 处理牙齿点击事件
	const handleToothClick = (tooth) => {
		if (props.disabled) return;
		emit('click');
		let sourceArray, targetArray;

		if (!props.maxillary) {
			sourceArray = double.value;
			targetArray = singular.value;
		} else {
			sourceArray = singular.value;
			targetArray = double.value;
		}

		const toothIdIndexInSource = sourceArray.indexOf(tooth.id);
		if (toothIdIndexInSource !== -1) {
			targetArray.push(sourceArray[toothIdIndexInSource]);
			sourceArray.splice(toothIdIndexInSource, 1);
		} else {
			const toothIdIndexInTarget = targetArray.indexOf(tooth.id);
			if (toothIdIndexInTarget !== -1) targetArray.splice(toothIdIndexInTarget, 1);
			else targetArray.push(tooth.id);
		}

		updateStyles();
	};

	// 处理颌部复选框变化
	const handleJawChange = (jaw) => {
		const isMaxillary = jaw === 'maxillary';

		const arr = sections.value
			.filter((s) => s.name.startsWith(isMaxillary ? 'upper' : 'lower'))
			.map((item) => item.teeth)
			.flat()
			.map((item) => item.id);

		const isJawActive = isMaxillary ? ymaxillary.value : ymandibular.value;

		if (isJawActive) {
			if (!props.maxillary) {
				singular.value = singular.value.concat(arr);
				double.value = double.value.filter((item) => !arr.includes(item));
			} else {
				double.value = double.value.concat(arr);
				singular.value = singular.value.filter((item) => !arr.includes(item));
			}
		} else {
			double.value = double.value.filter((item) => !arr.includes(item));
			singular.value = singular.value.filter((item) => !arr.includes(item));
		}

		updateStyles();
	};

	onMounted(() => {
		/** 更新牙齿样式 */
		updateWtchStyle();
	});

	// 更新复选框的样式
	const updateWtchStyle = () => {
		updateStyles();
		ymaxillary.value = getColorStatus('upper');
		ymandibular.value = getColorStatus('lower');
		onChanges();
	};

	const getColorStatus = (name) => sections.value.filter((s) => s.name.startsWith(name)).every((item) => item.teeth.every((t) => t.style.backgroundColor != '#eef4f1'));

	// 更新牙齿样式
	const updateStyles = () => {
		sections.value.forEach((section) =>
			section.teeth.forEach((tooth) => {
				tooth.style = toothStyle(tooth);
			})
		);
	};

	// 样式更新逻辑
	const toothStyle = (tooth) => {
		const isDoubleSelected = double.value.includes(tooth.id) && findAdjacentPairs(double.value).includes(tooth.id);
		const isSingularSelected = singular.value.includes(tooth.id) || separateAdjacentAndNonAdjacent(double.value).nonAdjacent.includes(tooth.id);
		return {
			backgroundColor: isSingularSelected ? '#ff9e00' : isDoubleSelected ? '#7FA8FF' : '#eef4f1',
			color: tooth.style.backgroundColor === '#eef4f1' ? 'black' : 'white'
		};
	};

	// 触发外部变更事件
	const onChanges = () => {
		emit('change', { singular: singular.value.map((item) => item).filter(Boolean) || [], double: double.value.map((item) => item).filter(Boolean) || [] });
	};
</script>

<style lang="scss" scoped>
	.tooth {
		display: flex;
		gap: 10px;
		user-select: none;

		.action {
			display: flex;
			flex-direction: column;
			gap: 15px;
		}
	}
	.toothPosition {
		display: grid;
		grid-template-columns: repeat(2, 1fr);

		&-item {
			display: flex;
			align-items: center;
			gap: 5px;
			height: 30px;

			&:nth-child(1) {
				justify-content: flex-end;
				border-right: 1px dashed rgba(0, 0, 0, 0.2);
				border-bottom: 1px dashed rgba(0, 0, 0, 0.2);
			}

			&:nth-child(2) {
				border-bottom: 1px dashed rgba(0, 0, 0, 0.2);
			}

			&:nth-child(3) {
				justify-content: flex-end;
				border-right: 1px dashed rgba(0, 0, 0, 0.2);
			}

			&-tooth {
				display: flex;
				justify-content: center;
				align-items: center;
				width: 30px;
				height: 30px;
				font-size: 14px;
				background-color: #eef4f1;
				border-radius: 5px;
				cursor: pointer;

				@media (max-width: 1500px) {
					width: 22px;
					height: 22px;
					border-radius: 0px;
				}
			}
		}
	}

	.toothdisabled {
		cursor: no-drop;
	}
</style>
